package com.kaibes.im.control.thread;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.ConnectException;
import java.net.Socket;
import java.net.UnknownHostException;

import android.os.Message;

import com.kaibes.im.KaibesApplication;
import com.kaibes.im.control.service.KaibesService;
import com.kaibes.im.model.SocketWorker;
import com.kaibes.im.model.hanlder.BaseHandler;

public class ConnectThread extends Thread {

    private String hostName;
    private Socket client;

    private InputStream is;
    private OutputStream os;

    private InputStreamReader isReader;
    private OutputStreamWriter osWriter;

    private BufferedReader bfReader;
    private BufferedWriter bfWriter;

    private String json;

    private BaseHandler<ConnectThread> handler = null;

    private KaibesApplication kaibesApplication = null;
    private KaibesService kaibesService = null;

    public ConnectThread(KaibesApplication kaibesApplication,
	    KaibesService kaibesService) {
	this.kaibesApplication = kaibesApplication;
	this.kaibesService = kaibesService;

	SocketWorker.newInstance(kaibesApplication, this);
	handler = new BaseHandler<ConnectThread>(this) {

	    @Override
	    public void handleMessage(Message msg) {
		switch (msg.what) {
		case 1:
		    getData().kaibesApplication.getCurrentActivity()
			    .getProgressDialogData().reset().setTitle("提示")
			    .setMessage("正在连接服务器。。。").setCancelable(false);
		    getData().kaibesApplication.getCurrentActivity()
			    .showProgressDialog();
		    break;

		case 2:
		    getData().kaibesApplication.getCurrentActivity()
			    .closeProgressDialog();
		default:
		    break;
		}
	    }

	};
	hostName = "imserver.kaibes.com";
	client = null;
    }

    @Override
    public void run() {

	while (client == null && kaibesApplication.getCurrentActivity()!=null) {

	    // 考虑后面重写这个部分，不出此提示，而是当连接没能成功连接的时候，再次连接才会出此提示
	    if (client == null) {
		// 改变UI，交给handler去做，可以使用Looper.prepare()，但这里不使用，直接交给hanlder要好得多了
		handler.sendEmptyMessage(1);
	    }

	    while (client == null) {
		try {
		    // client = new Socket(InetAddress.getByName(hostName)
		    // .getHostAddress(), 2015);
		    client = new Socket("10.0.3.2", 2015);

		    // 这里不能直接dismiss，因为创建progrdialog的动作是由hanlder去做的，我们并不知道它做的怎么样了
		    // 直接dismiss可能会出现空指针，所以也交给hanlder去做，等它昨晚上个任务会接着做这个任務
		    handler.sendEmptyMessage(2);
		} catch (UnknownHostException e) {
		    // e.printStackTrace();
		} catch (ConnectException e) {
		    // e.printStackTrace();
		} catch (IOException e) {
		    // e.printStackTrace();
		}

	    }

	    try {
		is = client.getInputStream();
		isReader = new InputStreamReader(is, "utf-8");
		bfReader = new BufferedReader(isReader);

		os = client.getOutputStream();
		osWriter = new OutputStreamWriter(os, "utf-8");
		bfWriter = new BufferedWriter(osWriter);
	    } catch (IOException e) {
		e.printStackTrace();
	    }

	    if (kaibesApplication.isMainActivity()&&!kaibesApplication.isLoginAgain()) {
		kaibesApplication.getCurrentActivity().try2Login();
	    } else if (kaibesApplication.getAccountPreferences().getBoolean("cbLogin",
		    false)) {
		kaibesApplication.sendData(
			1,
			SocketWorker.ACTION_LOGIN,
			kaibesApplication.getAccountPreferences().getString(
				"username", ""),
			kaibesApplication.getAccountPreferences().getString(
				"password", ""));
	    } 

	    while (client != null && !client.isClosed()) {
		try {
		    if (setJson(bfReader.readLine())) {
			SocketWorker.getInstance().callBack(json);
		    } else {
			// if (kaibesApplication.isMainActivity()) {
			// kaibesApplication.getCurrentActivity().back2Login();
			// }
			close();
		    }
		} catch (IOException e) {
		    System.err.println("线程死亡");
		    // TODO 线程死亡
		    // e.printStackTrace();
		}
	    }

	}
    }

    public void sendMessageln(String msg) {
	sendMessage(msg + "\n");
    }

    public void sendMessage(String data) {
	try {
	    bfWriter.write(data);
	    bfWriter.flush();
	} catch (IOException e) {
	    // TODO Auto-generated catch block
	    e.printStackTrace();
	}
    }

    public boolean isConnected() {
	if (client == null || client.isClosed()) {
	    return false;
	}

	return true;
    }

    public void close() {
	try {
	    bfReader.close();
	    bfWriter.close();

	    isReader.close();
	    osWriter.close();

	    is.close();
	    os.close();
	} catch (IOException e2) {
	    e2.printStackTrace();
	}

	try {
	    client.close();
	} catch (IOException e) {
	    e.printStackTrace();
	}

	client = null;
    }

    public void createReaderRunable(int num) {
	for (int i = 0; i < num; i++) {
	    new Thread(new ReaderRunable(bfReader)).start();
	}

    }

    // ---------------------------GET AND SET 1--------------------------

    private boolean setJson(String json) {
	if (json != null) {
	    this.json = json;
	    return true;
	} else {
	    return false;
	}
    }

    public Socket getClient() {
	return client;
    }

    public KaibesService getKaibesService() {
	return kaibesService;
    }

}
